using System;
using System.Collections;
using System.Windows.Forms;
using System.Xml;
using System.IO;

namespace WinCommand.SnippetManager
{
	/// <summary>
	/// Helper DAL class to deal with the management of snippet data.
	/// </summary>
	public class SnippetData
	{
//		private static CategoryCollection _categories = null;
//		public static CategoryCollection Categories
//		{
//			get
//			{
//				if (_categories == null)
//				{
//					_categories = new CategoryCollection();
////					_categories.Add("Common");
////					DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(Application.ExecutablePath));
////					FileInfo[] fis = di.GetFiles("*.snippets");
////					foreach (FileInfo fi in fis)
////					{
////						_categories.Add(Path.GetFileNameWithoutExtension(fi.Name));
////					}
//
//				}
//				return _categories;
//			}
//		}

		// Private constructor exists to prevent a default public constructor being
		// created by the compiler.
		private SnippetData() {}

		/// <summary>
		/// Save the snippets to disk in an XML file format (which happens to be the
		/// same structure as used by the ASP.NET Web Matrix Project for its own
		/// snippets).
		/// </summary>
		public static void SerializeSnippets(string filename, SnippetManagerData data)
		{
			CategoryCollection categories = data.Categories;
			ArrayList snippets = data.Snippets;

			XmlTextWriter writer = new XmlTextWriter(filename, System.Text.Encoding.UTF8);

			writer.WriteStartDocument(true);
			writer.WriteStartElement("Snippets");

			foreach (Category c in categories)
			{
				writer.WriteStartElement("Category");
				writer.WriteString(c.Name);
				writer.WriteEndElement();
			}
			foreach (Snippet s in snippets)
			{
				writer.WriteStartElement("Snippet");
				writer.WriteAttributeString("name", s.Name);
				writer.WriteAttributeString("category", s.Category);
				writer.WriteString(s.Code);
				writer.WriteEndElement();
			}
			writer.WriteEndDocument();
			writer.Close();
		}


		/// <summary>
		/// Loads a collection of snippets into memory from a file.
		/// </summary>
		public static SnippetManagerData DeserializeSnippets(string filename)
		{
			ArrayList snippets = new ArrayList();
			CategoryCollection categories = new CategoryCollection();
			XmlTextReader reader;
//			try 
//			{
				reader = new XmlTextReader(filename);

				while (reader.Read())
				{
					if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "Snippet"))
					{
						Snippet s = new Snippet();

						s.Name = reader.GetAttribute("name");
						reader.MoveToNextAttribute();
						string category = reader.GetAttribute("category");
						if ((category != null) && (category != String.Empty)) 
						{ 
							s.Category = category; 
						}

						reader.MoveToContent();
						s.Code = reader.ReadString();

						snippets.Add(s);
					}
					else
					{
						if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "Category"))
						{
							reader.MoveToContent();
							Category c = new Category(reader.ReadString());
							categories.Add(c);
						}
					}
				}
				reader.Close();
				return new SnippetManagerData(snippets, categories);
//			}
//			catch (System.IO.FileNotFoundException)
//			{
//				// We weren't able to find the original file
//				// swallow the exception - we'll simply create a new one...
//
//				return new SnippetManagerData(snippets, categories);
//			}
		}


		/// <summary>
		/// Find a unique name for a snippet, beginning with the supplied 
		/// prefix. We start with Snippet1 and test whether it exists already; 
		/// if so, we work our way up through Snippet2, Snippet3, ..., SnippetN. 
		/// This is rather inefficient but is probably satisfactory given the 
		/// relatively small number of items.
		/// </summary>
		public static string GetUniqueName(ArrayList snippets)
		{
			int id = 1;
			const string prefix = "Snippet ";
			bool nameIsUnique;

			do 
			{
				string proposedName = prefix + id.ToString();
				nameIsUnique = true;

				foreach (Snippet s in snippets)
				{
					if (s.Name == proposedName)
					{
						nameIsUnique = false;
						id++;
					}
				}
			} while (!nameIsUnique);

			return (prefix + id.ToString());
		}

		public static string GetUniqueCategoryName(CategoryCollection categories)
		{
			int id = 1;
			const string prefix = "Category ";
			bool nameIsUnique;

			do 
			{
				string proposedName = prefix + id.ToString();
				nameIsUnique = true;

				foreach (Category c in categories)
				{
					if (c.Name == proposedName)
					{
						nameIsUnique = false;
						id++;
					}
				}
			} while (!nameIsUnique);

			return (prefix + id.ToString());
		}

	}

	public class SnippetManagerData
	{
		private ArrayList _snippets;
		private CategoryCollection _categories;
		public SnippetManagerData(ArrayList snippets, CategoryCollection categories)
		{
			_snippets = snippets;
			_categories = categories;
		}
		public ArrayList Snippets
		{
			get { return _snippets; }
		}
		public CategoryCollection Categories
		{
			get { return _categories; }
		}
	}
}
